home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-09-28 | 24.8 KB | 766 lines | [TEXT/CWIE] |
- unit ICDialogs;
-
- (* This file is part of the Internet Configuration system and is placed in the public domain for the benefit of all.
-
- This module implements many many tiny little routines that are of great assistance
- to those who use the Dialog Manager as a user interface. Most of these routines
- are pretty obvious, so there's not a lot of comments in the interface section.
- However there may be comments in the implementation section that you might
- find interesting.
- *)
-
- interface
-
- uses
- Quickdraw,
- Dialogs;
-
- const
- ditOK = 1;
- ditCancel =2;
- ditDontSave = 3;
-
- (* ***** Better Getters and Setters ***** *)
-
- procedure GetDItemText (dlg: DialogPtr; item: integer; var text: Str255);
- procedure SetDItemText (dlg: DialogPtr; item: integer; text: Str255);
-
- procedure GetDItemKind (dlg: DialogPtr; item: integer; var kind: integer);
- procedure SetDItemKind (dlg: DialogPtr; item: integer; kind: integer);
- function GetDItemHandle (dlg: DialogPtr; item: integer): Handle;
- procedure SetDItemHandle (dlg: DialogPtr; item: integer; itemH: univ Handle);
- procedure GetDItemRect (dlg: DialogPtr; item: integer; var itemRect: Rect);
- procedure SetDItemRect (dlg: DialogPtr; item: integer; const itemRect: Rect);
-
- (* ***** Dialog Control Getters and Setters ***** *)
-
- function GetDControlHandle (dlg: DialogPtr; item: integer): ControlHandle;
-
- function GetDControlEnable (dlg: DialogPtr; item: integer): Boolean;
- procedure SetDControlEnable (dlg: DialogPtr; item: integer; enable: Boolean);
- function GetDControlTitle (dlg: DialogPtr; item: integer): Str255;
- procedure SetDControlTitle (dlg: DialogPtr; item: integer; title: Str255);
- function GetDControlValue (dlg: DialogPtr; item: integer): integer;
- procedure SetDControlValue (dlg: DialogPtr; item: integer; value: integer);
- function GetDControlMaximum (dlg: DialogPtr; item: integer): integer;
- procedure SetDControlMaximum (dlg: DialogPtr; item: integer; value: integer);
- function GetDControlBoolean (dlg: DialogPtr; item: integer): Boolean;
- procedure SetDControlBoolean (dlg: DialogPtr; item: integer; value: Boolean);
- procedure ToggleDControlBoolean (dlg: DialogPtr; item: integer);
-
- (* ***** Default Button Support ***** *)
-
- var
- gDefaultButtonUPP : UserItemUPP;
-
- procedure DefaultButtonUserItem (dlg: DialogPtr; item: integer);
- procedure SetupDefaultButtonUserItem (dlg: DialogPtr; defaultItem, roundRectUserItem: integer);
- (* See comment in implementation part. *)
-
- (* ***** Cool Filter Functions ***** *)
-
- (* Some of this functionality is subsumed by System 7's standard
- filter functions, but IC can't use them because it has to run
- under System 6.
-
- These routines are exported as both UPP and routines because
- some places in IC (such as filter functions that are layered
- on top of these default filter functions) need to call them directly.
- *)
-
- var
- gOKModalFilterUPP : ModalFilterUPP;
- gOKCancelModalFilter : ModalFilterUPP;
- gOKCancelDiscardModalFilter : ModalFilterUPP;
-
- function OKModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
- function OKCancelModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
- function OKCancelDiscardModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
-
- (* ***** Stuff That Should Be In the Dialog Manager ***** *)
-
- function CountDItems (dlg: DialogPtr): integer;
- function GetSelectedDialogTextItem (dlg: DialogPtr): integer;
- function DialogItemHidden(dlg : DialogPtr; item : integer) : Boolean;
- function GetDPopupMenuHandle (dlg: DialogPtr; item: integer): MenuHandle;
- procedure InvalDItem(dlg : DialogPtr; item : integer);
-
- (* ***** Miscellaneous Stuff ***** *)
-
- procedure DrawStyledString (dlg: DialogPtr; item: integer; styledString: Str255);
- procedure ShiftTab (dlg: DialogPtr);
- procedure FlashDItem (dlg: DialogPtr; item: integer);
- function TrackDItem(window : WindowPtr; item : integer) : Boolean;
-
- (* ***** Initialisation ***** *)
-
- procedure InitICDialogs;
-
- implementation
-
- uses
- TextUtils,
- Fonts,
- Sound,
-
- ICDebug,
- ICCommonSubs;
-
- (* ***** Better Getters and Setters ***** *)
-
- procedure GetDItemText (dlg: DialogPtr; item: integer; var text: Str255);
- var
- itemH: Handle;
- begin
- itemH := GetDItemHandle(dlg, item);
- GetDialogItemText(itemH, text);
- end; (* GetDItemText *)
-
- procedure SetDItemText (dlg: DialogPtr; item: integer; text: Str255);
- var
- itemH: Handle;
- begin
- itemH := GetDItemHandle(dlg, item);
- SetDialogItemText(itemH, text);
- end; (* SetDItemText *)
-
- procedure GetDItemKind (dlg: DialogPtr; item: integer; var kind: integer);
- var
- junkRect : Rect;
- junkItemH: Handle;
- begin
- GetDialogItem(dlg, item, kind, junkItemH, junkRect);
- end; (* GetDItemKind *)
-
- procedure SetDItemKind (dlg: DialogPtr; item: integer; kind: integer);
- var
- junkKind: integer;
- itemH: Handle;
- itemRect: Rect;
- begin
- GetDialogItem(dlg, item, junkKind, itemH, itemRect);
- SetDialogItem(dlg, item, kind, itemH, itemRect);
- end; (* SetDItemKind *)
-
- function GetDItemHandle (dlg: DialogPtr; item: integer): Handle;
- var
- itemKind: integer;
- itemH: Handle;
- itemRect: Rect;
- begin
- GetDialogItem(dlg, item, itemKind, itemH, itemRect);
- GetDItemHandle := itemH;
- end; (* GetDItemHandle *)
-
- procedure SetDItemHandle (dlg: DialogPtr; item: integer; itemH: univ Handle);
- var
- itemKind: integer;
- junkItemH: Handle;
- itemRect: Rect;
- begin
- GetDialogItem(dlg, item, itemKind, junkItemH, itemRect);
- SetDialogItem(dlg, item, itemKind, itemH, itemRect);
- end; (* SetDItemHandle *)
-
- procedure GetDItemRect (dlg: DialogPtr; item: integer; var itemRect: Rect);
- var
- itemKind: integer;
- itemH: Handle;
- begin
- GetDialogItem(dlg, item, itemKind, itemH, itemRect);
- end; (* GetDItemRect *)
-
- procedure SetDItemRect (dlg: DialogPtr; item: integer; const itemRect: Rect);
- var
- itemKind: integer;
- itemH: Handle;
- tmpItemRect: Rect;
- begin
- GetDialogItem(dlg, item, itemKind, itemH, tmpItemRect);
- tmpItemRect := itemRect;
- SetDialogItem(dlg, item, itemKind, itemH, tmpItemRect);
- end; (* SetDItemRect *)
-
- (* ***** Dialog Control Getters and Setters ***** *)
-
- function GetDControlHandle (dlg: DialogPtr; item: integer): ControlHandle;
- begin
- GetDControlHandle := ControlHandle(GetDItemHandle(dlg, item));
- end; (* GetDControlHandle *)
-
- function GetDControlEnable (dlg: DialogPtr; item: integer): Boolean;
- begin
- GetDControlEnable := (GetDControlHandle(dlg, item)^^.contrlHilite <> 255);
- end; (* GetDControlEnable *)
-
- procedure SetDControlEnable (dlg: DialogPtr; item: integer; enable: Boolean);
- var
- controlH: ControlHandle;
- newHighlight: integer;
- begin
- controlH := GetDControlHandle(dlg, item);
- newHighlight := (255 * ord(not enable));
- if controlH^^.contrlHilite <> newHighlight then begin
- HiliteControl(controlH, newHighlight);
- end; (* if *)
- end; (* SetDControlEnable *)
-
- function GetDControlTitle (dlg: DialogPtr; item: integer): Str255;
- var
- title: Str255;
- begin
- GetControlTitle(GetDControlHandle(dlg, item), title);
- GetDControlTitle := title;
- end; (* GetDControlTitle *)
-
- procedure SetDControlTitle (dlg: DialogPtr; item: integer; title: Str255);
- var
- controlH: ControlHandle;
- oldTitle: Str255;
- begin
- controlH := GetDControlHandle(dlg, item);
- GetControlTitle(controlH, oldTitle);
- if oldTitle <> title then begin
- SetControlTitle(controlH, title);
- end; (* if *)
- end; (* SetDControlTitle *)
-
- function GetDControlValue (dlg: DialogPtr; item: integer): integer;
- begin
- GetDControlValue := GetControlValue(GetDControlHandle(dlg, item));
- end; (* GetDControlValue *)
-
- procedure SetDControlValue (dlg: DialogPtr; item: integer; value: integer);
- begin
- SetControlValue(GetDControlHandle(dlg, item), value);
- end; (* SetDControlValue *)
-
- function GetDControlMaximum (dlg: DialogPtr; item: integer): integer;
- begin
- GetDControlMaximum := GetControlMaximum(GetDControlHandle(dlg, item));
- end; (* GetDControlMaximum *)
-
- procedure SetDControlMaximum (dlg: DialogPtr; item: integer; value: integer);
- begin
- SetControlMaximum(GetDControlHandle(dlg, item), value);
- end; (* SetDControlMaximum *)
-
- function GetDControlBoolean (dlg: DialogPtr; item: integer): Boolean;
- begin
- GetDControlBoolean := (GetControlValue(GetDControlHandle(dlg, item)) <> 0);
- end; (* GetDControlBoolean*)
-
- procedure SetDControlBoolean (dlg: DialogPtr; item: integer; value: Boolean);
- begin
- SetControlValue(GetDControlHandle(dlg, item), ord(value));
- end; (* SetDControlBoolean *)
-
- procedure ToggleDControlBoolean (dlg: DialogPtr; item: integer);
- begin
- SetDControlBoolean(dlg, item, not GetDControlBoolean(dlg, item));
- end; (* ToggleDControlBoolean *)
-
- (* ***** Default Button Support ***** *)
-
- procedure DefaultButtonUserItem (dlg: DialogPtr; item: integer);
- (* This routine is the user item update proc for the rounded rectangle
- user item that denotes the default button. It tests the enabled
- state of the default button (dialog item number 1) and draws the
- rounded rectangle in either grey or black depending on the state.
-
- Note that the dialog item number of the default button is hard
- coded into this routine. There will be no exceptions!
-
- This routine is exported because it can be called by the application
- directly when it thinks that the default button highlighting needs to be
- updated.
- *)
- var
- itemRect: Rect;
- greyPat : Pattern;
- begin
- {$unused item}
- SetPort(dlg);
- GetDItemRect(dlg, ditOK, itemRect);
- PenSize(3, 3);
- InsetRect(itemRect, -4, -4);
- if not GetDControlEnable(dlg, ditOK) then begin
-
- // Avoid using "qd.gray" so that we can be compiled
- // into a code resource. Sometimes programming the Mac
- // just sucks.
-
- StuffHex(@greyPat, 'AA55AA55AA55AA55');
- PenPat(greyPat);
- end; (* if *)
- FrameRoundRect(itemRect, 16, 16);
- PenNormal;
- end; (* DefaultButtonUserItem *)
-
- procedure SetupDefaultButtonUserItem (dlg: DialogPtr; defaultItem, roundRectUserItem: integer);
- (* This routine installs the DefaultButtonUserItem as the user item update
- proc for roundRectUserItem. It also sets the bounding rect of roundRectUserItem
- to exactly encompass the bounding rect of defaultItem, so that you don't
- have to get it exactly right when editing the dialog.
- *)
- var
- itemRect: Rect;
- begin
- ICAssert(defaultItem = 1);
- GetDItemRect(dlg, defaultItem, itemRect);
- InsetRect(itemRect, -10, -10);
- SetDItemRect(dlg, roundRectUserItem, itemRect);
- SetDItemHandle(dlg, roundRectUserItem, Handle(gDefaultButtonUPP));
- end; (* SetupDefaultButtonUserItem *)
-
- (* ***** Cool Filter Functions ***** *)
-
- function DoButtonKey (dlg: DialogPtr; item: integer;
- var event: EventRecord; var resultItem: integer): Boolean;
- (* This function is used to respond to a keyboard event hitting a dialog
- button. If the button denoted by dlg and item is enabled, the function
- flashes the button, sets resultItem to item, and returns true.
- Otherwise it beeps and sets event to a null event.
- *)
- begin
- if GetDControlEnable(dlg, item) then begin
- resultItem := item;
- FlashDItem(dlg, item);
- DoButtonKey := true;
- end else begin
- SysBeep(10);
- event.what := nullEvent;
- DoButtonKey := false;
- end;
- end; (* DoButtonKey *)
-
- function OKModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
- (* This is pretty much the standard modal dialog filter function. It handles
- mapping returns and enters to the ditOK button, and also deals with
- shift tab.
- *)
- var
- result : Boolean;
- typedChar: char;
- begin
- result := false;
- if (event.what = keyDown) or (event.what = autoKey) then begin
- typedChar := chr(band(event.message, charCodeMask));
- if (typedChar = kCRChar) or (typedChar = kEnterChar) then begin
- result := DoButtonKey(dlg, ditOK, event, item);
- end else if (typedChar = kTabChar) and (band(event.modifiers, shiftKey) <> 0) then begin
- if GetSelectedDialogTextItem(dlg) <> 0 then begin
- ShiftTab(dlg);
- result := true;
- end; (* if *)
- end; (* if *)
- end;
- OKModalFilter := result;
- end; (* OKModalFilter *)
-
- function OKCancelModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
- (* This is the standard modal filter for dialogs with an OK and a Cancel button.
- It handles all that OKModalFilter does, and then deals with mapping Escape
- and command-dot to ditCancel.
- *)
- var
- result : Boolean;
- typedChar: char;
- begin
- result := OKModalFilter(dlg, event, item);
- if not result and ((event.what = keyDown) or (event.what = autoKey)) then begin
- typedChar := chr(band(event.message, charCodeMask));
- if ((typedChar = '.') and (band(event.modifiers, cmdKey) <> 0))
- or (typedChar = kEscChar) then begin
- result := DoButtonKey(dlg, ditCancel, event, item);
- end; (* if *)
- end; (* if *)
- OKCancelModalFilter := result;
- end; (* OKCancelModalFilter *)
-
- function OKCancelDiscardModalFilter (dlg: DialogPtr; var event: EventRecord; var item: integer): Boolean;
- (* This is the standard modal filter for dialogs with an OK, Cancel and Dont Save button.
- It handles all that OKCancelModalFilter does, and then deals with mapping
- command-D to ditDontSave.
- *)
- var
- result : Boolean;
- typedChar: integer;
- begin
- result := OKCancelModalFilter(dlg, event, item);
- if not result and ((event.what = keyDown) or (event.what = autoKey)) then begin
- typedChar := band(event.message, charCodeMask);
- if (typedChar = ord('d')) and (band(event.modifiers, cmdKey) <> 0) then begin
- result := DoButtonKey(dlg, ditDontSave, event, item);
- end; (* if *)
- end; (* if *)
- OKCancelDiscardModalFilter := result;
- end; (* OKCancelDiscardModalFilter *)
-
- (* ***** Stuff That Should Be In the Dialog Manager ***** *)
-
- function CountDItems (dlg: DialogPtr): integer;
- (* Identical to CountDITL but works under System 6 without Comms Toolbox installed. *)
- begin
- CountDItems := IntegerPtr(DialogPeek(dlg)^.items^)^ + 1;
- end; (* CountDItems*)
-
- function GetSelectedDialogTextItem (dlg: DialogPtr): integer;
- (* Returns the item number of the edit text that contains the insertion point. *)
- begin
- GetSelectedDialogTextItem := DialogPeek(dlg)^.editField + 1;
- end; (* GetSelectedDialogTextItem *)
-
- function DialogItemHidden(dlg : DialogPtr; item : integer) : Boolean;
- (* Returns true if the item has been hidden with HideDialogItem. *)
- var
- itemRect : Rect;
- begin
- GetDItemRect(dlg, item, itemRect);
- DialogItemHidden := (itemRect.top < 16384) and (itemRect.left < 16384);
- end; (* DialogItemHidden *)
-
- function GetDPopupMenuHandle (dlg: DialogPtr; item: integer): MenuHandle;
- (* Returns the MenuHandle for the popup menu dialog item. This is documented
- as being available from the first 4 bytes of the handle pointed to be
- the item's contrlData field.
- *)
- type
- MenuHandlePtr = ^MenuHandle;
- MenuHandleHandle = ^MenuHandlePtr;
- begin
- GetDPopupMenuHandle := MenuHandleHandle(GetDControlHandle(dlg, item)^^.contrlData)^^;
- end; (* GetDPopupMenuHandle*)
-
- procedure InvalDItem(dlg : DialogPtr; item : integer);
- (* Invalidate a dialog item, ie cause it to be redrawn via an update event. *)
- var
- oldPort : GrafPtr;
- itemRect : Rect;
- begin
- GetPort(oldPort);
- SetPort(dlg);
- GetDItemRect(dlg, item, itemRect);
- InvalRect(itemRect);
- SetPort(oldPort);
- end; (* InvalDItem *)
-
- (* ***** Miscellaneous Stuff ***** *)
-
- function Split (delimiter : Str255; str: Str255; var head, tail: Str255): Boolean;
- (* This routine splits str at the first occurence of delimiter and sets
- head to be the text in front of the delimiter and tail to be the text
- behind it. It returns true if it could find a delimiter (and hence
- perform the split), otherwise it returns false.
- *)
- var
- delimiterPosition: integer;
- begin
- delimiterPosition := pos(delimiter, str);
- if delimiterPosition > 0 then begin
- head := TPCopy(str, 1, delimiterPosition - 1);
- tail := TPCopy(str, delimiterPosition + length(delimiter), 255);
- end; (* if *)
- Split := delimiterPosition > 0;
- end; (* Split *)
-
- procedure DrawStyledString (dlg: DialogPtr; item: integer; styledString: Str255);
- (* This function draws the dialog item based on the styledString. styledString
- is a colon delimited set of fields that determines how the string is to be
- drawn. The general format is:
-
- font:size:style:justification:text
-
- Any of these fields can be left blank but the colons must remain.
-
- If font is blank, Geneva is used.
- If size is blank, 9 point is used.
- style is a string with 0 or more characters. The characters 0..6
- turn on the corresponding StyleItem in the style. An 'h' character
- makes the text hot, ie the routine searches out text enclosed
- in angle brackets and draws it in blue underline mode.
- If justification is blank, teJustLeft is used.
- The text field is simply drawn to the screen.
-
- The implementation of this routine is typical "Peter code", ie
- a million line procedure. I just don't have the guts to
- break it up into more readable chunks. Sorry.
- *)
- const
- defaultSize = 9;
- var
- defaultFont : integer;
-
- itemRect: Rect;
- oldFont : integer;
- oldSize: integer;
- oldFace: Style;
-
- fixSize: Boolean;
- textIsHot : Boolean;
-
- goingFine : Boolean;
- this: Str255;
-
- fontNumber : integer;
- fontSize : integer;
- fontStyle: Style;
- justification: integer;
-
- stringIndex : integer;
- indexOfEndOfURL : integer;
-
- fi: FontInfo;
- textEditH : TEHandle;
- textStyleRecord : TextStyle;
- begin
- SetPort(dlg);
-
- GetFNum("Geneva", defaultFont);
-
- GetDItemRect(dlg, item, itemRect);
-
- (* Save the current window state. *)
- oldFont := dlg^.txFont;
- oldSize := dlg^.txSize;
- oldFace := dlg^.txFace;
-
- textIsHot := false;
- fixSize := false;
-
- goingFine := Split(':', styledString, this, styledString);
- (* Interpret the font part of styledString. An empty string means
- use the default font, otherwise use the string as the font name.
- *)
- if goingFine then begin
- if this = '' then begin
- fontNumber := defaultFont;
- end else begin
- GetFNum(this, fontNumber);
- if fontNumber = 0 then begin
- fixSize := true;
- fontNumber := defaultFont;
- end; (* if *)
- end; (* if *)
- goingFine := Split(':', styledString, this, styledString);
- end; (* if *)
-
- (* Interpret the size part of styledString. An empty string denotes
- the default size, otherwise evaluate the string and use that size.
- *)
- if goingFine then begin
- if this = '' then begin
- fontSize := defaultSize;
- end else begin
- fontSize := DecVal(this);
- end; (* if *)
- goingFine := Split(':', styledString, this, styledString);
- end; (* if *)
-
- (* Interpret the style part of styledString. Loop through the string
- setting styles based on the digits in the style string.
- *)
- if goingFine then begin
- fontStyle := [];
- for stringIndex := 1 to length(this) do begin
- case this[stringIndex] of
- '0'..'7':
- fontStyle := fontStyle + [StyleItem(ord(this[stringIndex]) - ord('0'))];
- 'H', 'h':
- textIsHot := true;
- otherwise
- (* do nothing *);
- end; (* case *)
- end; (* for *)
- goingFine := Split(':', styledString, this, styledString);
- end; (* if *)
-
- (* Interpret the justification part of styledString. An empty string
- means the default justification (ie teJustLeft) and any other string
- is interpreted as a numeric value suitable for passing to TESetAlignment.
- *)
- if goingFine then begin
- if this = '' then begin
- justification := teJustLeft;
- end else begin
- justification := DecVal(this);
- end; (* if *)
- TextFont(fontNumber);
- TextSize(fontSize);
- TextFace(fontStyle);
-
- (* Now fix the text size. I actually have *no idea* what this is for. *)
- if fixSize then begin
- GetFontInfo(fi);
- while (fi.ascent + fi.descent > itemRect.bottom - itemRect.top) do begin
- if fontSize > 48 then begin
- fontSize := 48;
- end else if fontSize > 36 then begin
- fontSize := 36;
- end else if fontSize > 27 then begin
- fontSize := 27;
- end else if fontSize > 24 then begin
- fontSize := 24;
- end else if fontSize > 18 then begin
- fontSize := 18;
- end else if fontSize > 14 then begin
- fontSize := 14;
- end else if fontSize > 12 then begin
- fontSize := 12;
- end else begin
- fontSize := 9;
- TextSize(fontSize);
- leave;
- end; (* if *)
- TextSize(fontSize);
- GetFontInfo(fi);
- end; (* while *)
- end; (* if *)
-
- (* Now actually go and draw the text. First create a TEStyleHandle. *)
- textEditH := TEStyleNew(itemRect,itemRect);
- if textEditH <> nil then begin
-
- (* Now install the text and setup the justification. *)
- TESetText(@styledString[1],length(styledString),textEditH);
- TESetAlignment(justification, textEditH);
-
- (* If the text is hot, search out text enclosed in < > and make it
- blue underlined.
- *)
- if textIsHot then begin
- for stringIndex := 1 to length(styledString) do begin
- if styledString[stringIndex] = '<' then begin
- indexOfEndOfURL := stringIndex + 1;
- while (indexOfEndOfURL <= length(styledString)) & (styledString[indexOfEndOfURL] <> '>') do begin
- indexOfEndOfURL := indexOfEndOfURL + 1;
- end; (* while *)
- TESetSelect(stringIndex, indexOfEndOfURL - 1, textEditH);
- textStyleRecord.tsFace := fontStyle + [underline];
- textStyleRecord.tsColor.red := 0;
- textStyleRecord.tsColor.green := 0;
- textStyleRecord.tsColor.blue := $FFFF;
- TESetStyle(doFace + doColor, textStyleRecord, false, textEditH);
- end; (* if *)
- end; (* for *)
- end; (* if *)
-
- (* Finally, draw the text and dispose the TEStyleHandle. *)
- TEUpdate(itemRect, textEditH);
- TEDispose(textEditH);
- end; (* if *)
- end; (* if *)
-
- (* Clean up. *)
- TextFont(oldFont);
- TextSize(oldSize);
- TextFace(oldFace);
- end; (* DrawStyledString *)
-
- procedure ShiftTab (dlg: DialogPtr);
- (* Performs a shift tab operation in the dialog, ie moves the text selection
- to the edit text item immediately before the current one.
-
- This code doesn't deal well with there being no currently selected
- text. Fortunately that case never comes up, because IC always
- selects the first text item before bringing up a dialog. Something to
- work on later I guess.
- *)
-
- function IsVisibleEditText(dlg : DialogPtr; item : integer) : Boolean;
- var
- kind: integer;
- begin
- GetDItemKind(dlg, item, kind);
- IsVisibleEditText := ((kind = editText) & DialogItemHidden(dlg, item));
- end; (* IsVisibleEditText *)
-
- var
- originalItem : integer;
- itemIndex : integer;
- itemCount: integer;
- begin
- originalItem := GetSelectedDialogTextItem(dlg);
- itemCount := CountDItems(dlg);
-
- (* We only have to do work if there's more than one item in the dialog.
- Also bail out of there's no text selected because we don't deal with that case
- *)
- if (originalItem > 0) and (itemCount > 1) then begin
-
- (* Start at the originalItem and walk backwards looking for
- an unhidden text item. If itemIndex hits 0, wrap around
- to the last item. Stop if we get back to the original
- item or we find an item.
- *)
- itemIndex := originalItem;
- repeat
- itemIndex := itemIndex - 1;
- if itemIndex = 0 then begin
- itemIndex := itemCount;
- end; (* if *)
- until (itemIndex = originalItem) | IsVisibleEditText(dlg, itemIndex);
- if (itemIndex <> originalItem) & IsVisibleEditText(dlg, itemIndex) then begin
- SelectDialogItemText(dlg, itemIndex, 0, 32767);
- end; (* if *)
- end; (* if *)
- end; (* ShiftTab *)
-
- procedure FlashDItem (dlg: DialogPtr; item: integer);
- (* Flashes a dialog item by highlighting its control, waiting for 2 ticks
- and then unhighlighting it.
- *)
- var junk : UInt32;
- begin
- HiliteControl(GetDControlHandle(dlg, item), kControlButtonPart);
- Delay(2,junk);
- HiliteControl(GetDControlHandle(dlg, item), 0);
- end; (* FlashDItem*)
-
- function TrackDItem(window : WindowPtr; item : integer) : Boolean;
- (* Tracks the mouse within the dialog item, returning true
- if the mouse is released inside the item.
- *)
- var
- itemRect : Rect;
- inside : Boolean;
- newInside : Boolean;
- mousePosition : Point;
- begin
- SetPort(window);
- GetDItemRect(window, item, itemRect);
- InvertRect(itemRect);
- inside := true;
- while StillDown do begin
- GetMouse(mousePosition);
- newInside := PtInRect(mousePosition, itemRect);
- if newInside <> inside then begin
- InvertRect(itemRect);
- inside := newInside;
- end; (* if *)
- end; (* while *)
- if inside then begin
- InvertRect(itemRect);
- end; (* if *)
- TrackDItem := inside;
- end; (* TrackDItem *)
-
- (* ***** Initialisation ***** *)
-
- procedure InitICDialogs;
- begin
- gDefaultButtonUPP := NewUserItemProc(@DefaultButtonUserItem);
- ICAssert(gDefaultButtonUPP <> nil);
-
- gOKModalFilterUPP := NewModalFilterProc(@OKModalFilter);
- ICAssert(gOKModalFilterUPP <> nil);
-
- gOKCancelModalFilter := NewModalFilterProc(@OKCancelModalFilter);
- ICAssert(gOKCancelModalFilter <> nil);
-
- gOKCancelDiscardModalFilter := NewModalFilterProc(@OKCancelDiscardModalFilter);
- ICAssert(gOKCancelDiscardModalFilter <> nil);
- end; (* InitICDialogs *)
-
- end. (* ICDialogs *)
-